package com.xbongbong.pay.platform.wechatpay.utils;

import com.xbongbong.paas.toolbox.util.DateTimeUtil;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 *
 * @author 魏荣杰
 * @date 2021/1/15 14:04
 * @since
 * @version
 */
public class WeChatPayHelp {



    /**
     * 构建 v3 接口所需的 Authorization
     *
     * @param method    请求方法 get,post
     * @param urlSuffix
     * @param mchId     商户Id
     * @param serialNo  商户 API 证书序列号
     * @param privateKey   商户私钥
     * @param body      接口请求参数
     * @param authType  认证类型 WECHATPAY2-SHA256-RSA2048
     * @return {@link String} 返回 v3 所需的 Authorization
     * @throws Exception 异常信息
     */
    public static String buildAuthorization4V3(String method, String urlSuffix, String mchId,
                                               String serialNo, PrivateKey privateKey, String body, String authType) throws Exception {
        String nonceStr = UUID.randomUUID().toString().replaceAll("-", "");
        long timestamp = DateTimeUtil.getInt();
        // 构建签名参数
        String buildSignMessage = WeChatSignUtil.buildSignMessage(method, urlSuffix, timestamp, nonceStr, body);

        String signature = WeChatSignUtil.createSign4V3(buildSignMessage, privateKey);
        // 根据平台规则生成请求头 authorization
        return getAuthorization(mchId, serialNo, nonceStr, String.valueOf(timestamp), signature, authType);
    }

    private static String getAuthorization(String mchId, String serialNo, String nonceStr, String timestamp, String signature, String authType) {
        Map<String, String> params = new HashMap<>(5);
        params.put("mchid", mchId);
        params.put("serial_no", serialNo);
        params.put("nonce_str", nonceStr);
        params.put("timestamp", timestamp);
        params.put("signature", signature);
        return authType.concat(" ").concat(createLinkString(params, ",", false, true));
    }


    /**
     * Description:
     * @param params 拼接的参数
     * @param connStr 中间连接符
     * @param encode 是否url编码
     * @param quotes 是否加引号
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2021/1/15 15:42
     * @since
     */
    public static String createLinkString(Map<String, String> params, String connStr, boolean encode, boolean quotes) {
        List<String> keys = new ArrayList<>(params.keySet());
        Collections.sort(keys);
        StringBuffer content = new StringBuffer();
        for (int i = 0; i < keys.size(); i++) {
            String key = keys.get(i);
            String value = params.get(key);
            // 拼接时，不包括最后一个&字符
            if (i == keys.size() - 1) {
                if (quotes) {
                    content.append(key).append("=").append('"').append(encode ? urlEncode(value) : value).append('"');
                } else {
                    content.append(key).append("=").append(encode ? urlEncode(value) : value);
                }
            } else {
                if (quotes) {
                    content.append(key).append("=").append('"').append(encode ? urlEncode(value) : value).append('"').append(connStr);
                } else {
                    content.append(key).append("=").append(encode ? urlEncode(value) : value).append(connStr);
                }
            }
        }
        return content.toString();
    }

    /**
     * URL 编码
     *
     * @param src 需要编码的字符串
     * @return 编码后的字符串
     */
    public static String urlEncode(String src) {
        try {
            return URLEncoder.encode(src, "utf-8").replace("+", "%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

}
